/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ve.usb.cep.actions;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;
import java.sql.Array;
import java.util.HashMap;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;

import ve.usb.cep.db.SelectObject;
import ve.usb.cep.db.domainObjects.Usuario;
import ve.usb.cep.db.domainObjects.Oferta;
import ve.usb.cep.db.domainObjects.Curso;
import ve.usb.cep.db.models.OfertaModel;
import ve.usb.cep.db.models.CursoModel;
import ve.usb.cep.db.modelExceptions.OfertaException;
import ve.usb.cep.db.modelExceptions.CursoException;
import ve.usb.cep.util.sqlWhere;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import ve.usb.cep.db.Session;
/**
 *
 * @author Andras
 */
public class OfertaA extends ActionSupport{

    //Salida por texto
    protected String output;
    protected String error;
    protected HashMap err = new HashMap();

	public String execute_l(){
        try {
            Usuario u = (Usuario) ActionContext.getContext().getSession().get("user");
            if (u!=null) {
                /*if (!"Estudiante".equals(user().getRol())){
                    error = "Sólo estudiantes pueden ver el listado de ofertas para inscribir.";
                    return ERROR;
                }*/

                System.out.println("ANTES DEL CONNECTION!!!!!!!!!!!");
                Connection conn = Session.connection();
                ResultSet rs;
                PreparedStatement pstmt;
                pstmt = conn.prepareStatement("select count(*) from exonerado where estudiante = ?");
                pstmt.setInt(1,u.getCodigo());
                rs = pstmt.executeQuery();
                System.out.println("DESPUES DE LA CUENTA!!!!!!!!!!!!");
                rs.next();
                int cantidadOfertas = rs.getInt(1);
                pstmt = conn.prepareStatement("select * from exonerado where estudiante = ?");
                pstmt.setInt(1,u.getCodigo());
                rs = pstmt.executeQuery();
                String ofertas = "";
                int i = 0;
                while (rs.next()) {
                    if (i==0){
                        ofertas = ""+rs.getInt("oferta");
                        i=1;
                    } else {
                        ofertas = ofertas+","+rs.getInt("oferta");
                    }
                }
                System.out.println("**** Y LAS OFERTAS EXONERADAS SON "+ofertas);
                ActionContext.getContext().getSession().put("nroOfertasExoneradas",cantidadOfertas);
                ActionContext.getContext().getSession().put("codOfertasExoneradas",ofertas);
                
                pstmt = conn.prepareStatement("select o.codigo from oferta o, inscripcion i where o.curso = i.curso and i.estudiante = ?");
                pstmt.setInt(1,u.getCodigo());
                rs = pstmt.executeQuery();
                
                ofertas = "";
                i = 0;
                while (rs.next()) {
                    if (i==0){
                        ofertas = ""+rs.getInt(1);
                        i=1;
                    } else {
                        ofertas = ofertas+","+rs.getInt(1);
                    }
                }
                ActionContext.getContext().getSession().put("codOfertasCursosInscritos",ofertas);
            }
            return SUCCESS;
        } catch (SQLException ex) {
            Logger.getLogger(OfertaA.class.getName()).log(Level.SEVERE, null, ex);
            return ERROR;
        }
    }
	
    public String crear(){

        if (!"Administrador".equals(user().getRol())){
            err.put("error", "debe ser administrador para crear oferta");
            return _finish();
        }

        return editar();
    }

    public String editar(){

        if (!"Administrador".equals(user().getRol())){
            err.put("error", "debe ser administrador para modificar la oferta");
            return _finish();
        }

        try{
            Oferta o = _createDomainObject(), exist;
            if (null != o){
                try{
                    exist = new OfertaModel().getUnique(o.getCurso(),
                            o.getPeriodo(), o.getAno(), o.getDias(), o.getCodigo());
                }catch(OfertaException e){
                    return _finishWithExceptions(e);
                }
                HttpServletRequest r = ServletActionContext.getRequest();
                if (null != exist){
                    err.put("Curso", "Ya existe una oferta (" +
                            r.getParameter("curso") + ", " +
                            exist.getPeriodo() + ", " + exist.getAno() +
                            ", " + exist.getDias() +
                            ") registrada con esos datos.");
                }
            }
            if (!err.isEmpty()){
                return _finish();
            }
            new OfertaModel().set(o);
        }catch(OfertaException e){
            return _finishWithExceptions(e);
        }
        return _finish();
    }

    public String listar(){
        OfertaModel p = new OfertaModel();
        SelectObject s;
        ArrayList<Oferta> ofertas;
        int rowCount;
        try{
            s = _createSearchObject();
            if (!err.isEmpty()){
                return _finish();
            }
            p = new OfertaModel();
            ofertas = p.getCustom(s);
            rowCount = p.getRowCount();
        }catch (OfertaException e){
            return _finishWithExceptions(e);
        }
        if (!err.isEmpty()){
            return _finish();
        }

        HashMap[] m = new HashMap[ofertas.size()];
        int i = 0;

        sqlWhere w = new sqlWhere();
        sqlWhere.rule[] a = new sqlWhere.rule[ofertas.size()];
        /*for (Oferta o : ofertas){
            String[] c = new String[6];
            c[0] = Integer.toString(o.getCurso());
            c[1] = o.getAno().toString();
            c[2] = o.getPeriodo().toString();
            c[3] = Integer.toString(o.getInscritos());
            c[4] = 1 == o.getAbierto() ? "SI" : "NO";
            c[5] = o.getDias();
            HashMap e = new HashMap();
            e.put("id", o.getCodigo());
            e.put("cell", c);
            m[i] = e;

            a[i] = w.new rule();
            a[i].setField("codigo");
            a[i].setOp("eq");
            a[i].setData(c[0]);

            ++ i;
        }*/

        for (Oferta o : ofertas){
            String[] c = new String[2];
            c[0] = Integer.toString(o.getCurso());
            c[1] = o.getDias();
            HashMap e = new HashMap();
            e.put("id", o.getCodigo());
            e.put("cell", c);
            m[i] = e;

            a[i] = w.new rule();
            a[i].setField("codigo");
            a[i].setOp("eq");
            a[i].setData(c[0]);

            ++ i;
        }
        
        w.setGroupOp(" OR ");
        w.setRules(a);
        ArrayList<Curso> cursos;
        try{
            cursos = new CursoModel().getCustom(
                new SelectObject(
                    (short) ofertas.size(),
                    (short) 1,
                    "codigo",
                    "asc",
                    w
                )
            );
        }catch(CursoException e){
            return _finishWithExceptions(e);
        }

        i = 0;
        for (Oferta o : ofertas){
            for (Curso c : cursos){
                if (o.getCurso() == c.getCodigo()){
                    ((String[]) m[i].get("cell"))[0] = c.getNombre();
                }
            }
            ++ i;
        }
        HashMap r = new HashMap();
        r.put("total", Math.ceil((double) rowCount / (double) s.getRows()));
        r.put("page", s.getPage());
        r.put("records", s.getRows());
        r.put("rows", m);
 
        output = new Gson().toJson(r);

        return SUCCESS;
    }

    public String eliminar(){

        if (!"Administrador".equals(user().getRol())){
            err.put("error", "debe ser administrador para eliminar cursos");
            return _finish();
        }

        HttpServletRequest r = ServletActionContext.getRequest();
        int codigo = 0;
        try{
            codigo = Integer.parseInt(r.getParameter("id"));
        }catch(java.lang.NumberFormatException e){
            err.put("Código", "El registro con el número '" + r.getParameter("id") + "' no existe.");
        }

        if (!err.isEmpty()){
            return _finish();
        }

        try{
            new OfertaModel().delete(codigo);
            return _finish();
        }catch (OfertaException e){
            return _finishWithExceptions(e);
        }
    }

    protected Oferta _createDomainObject()
        throws OfertaException
    {

        HttpServletRequest r = ServletActionContext.getRequest();
        int curso = _getCodigoFromCurso(r.getParameter("curso"));

        int codigo = -1;
        if ("_empty".equals(r.getParameter("id"))){
            codigo = 0;
        }else{
            try{
                codigo = Integer.parseInt(r.getParameter("id"));
            }catch(java.lang.NumberFormatException e){
                err.put("Codigo", "Número de registro inválido");
            }
        }

        short inscritos = -1;
        try{
            inscritos = (short) Integer.parseInt(r.getParameter("inscritos"));
            if (inscritos < 0){
                err.put("Inscritos", "El número de inscritos no puede ser negativo");
            }
        }catch(java.lang.NumberFormatException e){
            err.put("Inscritos", "Número de inscritos inválido");
        }

        return new Oferta(
            codigo,
            curso,
            r.getParameter("ano"),
            r.getParameter("periodo"),
            inscritos,
            (short) ("SI".equals(r.getParameter("abierto")) ? 1 : 0),
            r.getParameter("dias")
        );
    }

    protected int _getCodigoFromCurso(String curso)
        throws OfertaException
    {

        sqlWhere w = new sqlWhere();
        sqlWhere.rule[] c = new sqlWhere.rule[1];
        c[0] = w.new rule();
        c[0].setField("nombre");
        c[0].setOp("eq");
        c[0].setData(curso);
        w.setRules(c);

        ArrayList<Curso> cursos = null;
        try{
            cursos = new CursoModel().getCustom(new SelectObject((short) 1,
                    (short) 1,
                    "nombre",
                    "asc",
                    w
            ));
        }catch (CursoException e){
            throw new OfertaException("Error en cursos: " + e.getMessage());
        }
 
        if (null == cursos || 0 == cursos.size()){
            err.put("Curso", "El curso '" + curso + "' no existe");
            return -1;
        }

        return cursos.get(0).getCodigo();
    }

    protected SelectObject _createSearchObject()
        throws OfertaException
    {

        HttpServletRequest r = ServletActionContext.getRequest();
        sqlWhere w = (sqlWhere) new Gson().fromJson(
                r.getParameter("filters"), sqlWhere.class);
        if (null == w){
            w = new sqlWhere();
        }

        //Convertir la búsqueda del nombre en la búsqueda de enteros
        if (null != w.getRules()){
            for (sqlWhere.rule c : w.getRules()){
                if ("curso".equals(c.getField())){
                    c.setData(Integer.toString(_getCodigoFromCurso(c.getData())));
                }
            }
        }

        short rows = 20, page = 1;
        try{
            rows = (short) Integer.parseInt(r.getParameter("rows"));
            page = (short) Integer.parseInt(r.getParameter("page"));
        }catch(java.lang.NumberFormatException e){
            
        }
        return new SelectObject(
            rows,
            page,
            r.getParameter("sidx"),
            r.getParameter("sord"),
            w
        );
    }

    protected String _finishWithExceptions(Exception e){
        ServletActionContext.getResponse()
                .setStatus(HttpServletResponse.SC_BAD_REQUEST);

        //Para los casos en los que el error sea interno, err estará vacío.
        if (null != e){
            e.printStackTrace();
            err.put("error interno", e.getMessage());
            output = new Gson().toJson(err);
        }
        return ERROR;
    }

    protected String _finish(){
        if (!err.isEmpty()){
            ServletActionContext.getResponse()
                .setStatus(HttpServletResponse.SC_BAD_REQUEST);
            output = new Gson().toJson(err);
            return ERROR;
        }

        return SUCCESS;
    }

    protected Usuario user(){

        Usuario u = (Usuario) ActionContext.getContext().getSession().get("user");
        if (null == u){
            u = new Usuario(0, "", "", "", 0, "Visitante", "", "", "", "");
        }
        return u;
    }

    //Output, salida estándar por texto
    public String getOutput() {
        return output;
    }

    public String getError(){
        return error;
    }
}
